<!--
 * @Descripttion: 定制表单选项
 * @Author: caijj
 * @Date: 2020-12-14 17:51:30
 * @LastEditors: caijj
 * @LastEditTime: 2020-12-22 15:38:26
-->

<template>
  <el-form
    ref="custom-form"
    :inline="inline"
    :model="formData"
    v-bind="$attrs"
    v-on="$listeners"
  >
    <el-row>
      <template v-for="item in configOptions">
        <!-- 完美的分割线 -->
        <el-col v-if="item.split" :key="item.key" class="split-col" :span="24">
          <slot :name="item.slotName" />
        </el-col>
        <!-- 循环遍历表单项 -->
        <el-col v-else :key="item.prop" :span="spanCol">
          <el-form-item
            :prop="item.prop"
            :label="item.label ? item.label + '：' : ''"
            :rules="item.rules || undefined"
          >
            <!-- 启用具名插槽 -->
            <slot v-if="item.slot" :name="item.prop" />
            <!-- 不使用插槽 -->
            <formItem v-else v-model="formData[item.prop]" :item-props="item" />
          </el-form-item>
        </el-col>
      </template>
      <el-col :span="opearteSpan" style="margin-left:10px;">
        <el-form-item
          v-if="showOpearte"
          :class="[right ? 'right' : '', left ? 'left' : '']"
        >
          <template v-for="item in handler">
            <el-button
              :key="item.prop"
              v-debounce:switchEvent="item"
              :type="item.type"
              :icon="item.icon"
              :style="{
                width: item.width
              }"
            >
              {{ item.label }}
            </el-button>
          </template>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>

<script>
import formItem from './FormItem';

export default {
  components: { formItem },
  props: {
    /**
     * 表单配置
     * 示例：
     * [{
        label: '用户名', // label文字
        prop: 'username', // 字段名
        element: 'el-input', // 指定elementui组件
        tagProps: { options:[] }, //元素传递的属性
        initVal: '阿黄', // 字段初始值
        placeholder: '请输入用户名', // elementui组件属性
        rules: [{ required: true, message: '必填项', trigger: 'blur' }], // elementui组件属性
        events: { // elementui组件方法
          input (val) {
            console.log(val)
          },
        },
      ...... // 可添加任意elementui组件支持的属性
      }]
     */
    configOptions: {
      type: Array,
      required: true,
      default() {
        return [];
      }
    },
    inline: {
      type: Boolean,
      default: false
    },
    right: {
      type: Boolean,
      default: false
    },
    left: {
      type: Boolean,
      default: false
    },
    spanCol: {
      type: Number,
      default: 4
    },
    opearteSpan: {
      type: Number,
      default: 4
    },
    // 是否展示操作面板
    showOpearte: {
      type: Boolean,
      default: true
    },
    // 表单处理事件
    handler: {
      type: Array,
      default: () => [
        {
          icon: 'el-icon-search',
          label: '查询', // 按钮名称
          prop: 'submit', // 属性关键字
          type: 'primary', // el-button 按钮类型
          eventName: 'onSubmit' // 定义事件名称
        },
        {
          icon: 'el-icon-refresh-left',
          label: '重置', // 按钮名称
          prop: 'reset', // 属性关键字
          type: 'default', // el-button 按钮类型
          eventName: 'onReset' // 定义事件名称
        }
      ]
    }
  },
  data() {
    return {
      formData: {}
    };
  },
  created() {
    // 创建时初始化表单数据
    this.setFormDataVal(this.configOptions);
  },
  methods: {
    // 切换事件
    switchEvent({ prop, eventName }) {
      switch (prop) {
        case 'submit':
          return this.sumitFrom(eventName);
        case 'reset':
          return this.resetForm(eventName);
        default:
          return this.otherEvent(eventName);
      }
    },
    // 提交表单
    sumitFrom(eventName) {
      const self = this;
      this.$refs['custom-form'].validate(valid => {
        if (valid) self.$emit(eventName, self.formData);
      });
    },
    // 重置表单
    resetForm(eventName) {
      this.$refs['custom-form'].resetFields();
      this.$emit(eventName, self.formData);
    },
    // 其他定制事件
    otherEvent(eventName) {
      this.$emit(eventName);
    },
    // 创建初始化值接口
    createInitValue(options) {
      this.configOptions.forEach(option => {
        this.setFormDataVal(option);
      });
    },
    // 设置表单的值
    setFormDataVal(options) {
      if (Array.isArray(options) && options.length === 0) return;
      options.forEach(({ initVal = undefined, prop = '' }) => {
        !!prop && this.$set(this.formData, prop, initVal);
      });
    }
  }
};
</script>
<style lang="scss" scoped>
.split-col {
  height: 40px;
  line-height: 40px;
  margin-bottom: 20px;
}
</style>
